<?php

namespace zhuli\core;

use ReflectionClass;
use Exception;

class DependencyInterface implements DiInterface
{
	private $dependency = [];
	
	public function set($class, $args = [])
	{
		$this->dependency[$class] = $args;
	}

	public function get($class, $args = [])
	{
		$reflectClass = new ReflectionClass($class);
		if ($reflectClass->isInterface()) {
			$interfaceName = $reflectClass->getName();
			//print_r($interfaceName);die;
			if (!isset($this->dependency[$interfaceName])) {
				throw new Exception("The Interface $interfaceName is not exit!");
			}
			$reflectClass = new ReflectionClass($this->dependency[$interfaceName]);
		}

		$constructor = $reflectClass->getConstructor();
		$targetClass = $reflectClass->getName();
		if ($constructor && $params = $constructor->getParameters()) {
			$passParams = [];
			foreach ($params as $position => $param) {
				$dependencyClass = $param->getClass();
				if ($dependencyClass instanceof ReflectionClass) {
					$dependencyClassName = $dependencyClass->getName();
					if (isset($this->dependency[$dependencyClassName])) {
						$passParams[$position] = $this->get($dependencyClassName, $this->dependency[$dependencyClassName]);
					} else {
						$passParams[$position] = $this->get($dependencyClassName);
					}
				} else {
					$paramName = $param->getName();
					if (isset($args[$paramName])) {
						$passParams[$position] = $args[$paramName];
					} elseif (isset($this->dependency[$targetClass])) {
						if (isset($this->dependency[$targetClass][$paramName])) {
							$passParams[$position] = $this->dependency[$targetClass][$paramName];
						}
					} else {
						$passParams[$position] = $param->getDefaultaValue();
					}
				}
			}
			return $reflectClass->newInstanceArgs($passParams);
		} else {
			return $reflectClass->newInstance();
		}
	}
}